﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Timers;
using UploadClient.Interfaces.Plugins;

namespace RegionShotPlugin
{
    public class RegionShot : IPlugin
    {
        private Bitmap bitmap;
        private Point clickEnd;
        private Point clickStart;

        Configurations config;
        IHost host;
        private MouseInput mouse;
        private Timer update;

        #region IPlugin Members

        public void Init(IHost host)
        {
            mouse = new MouseInput(false);
            config = new Configurations(host);
            this.host = host;
        }

        public void Init(IHost host, IPluginConfig settings)
        {
            Init(host, settings);
        }

        public IEnumerable<IPluginConfig> GetConfiguration()
        {
            return new IPluginConfig[] { config };
        }

        public void EnablePlugin()
        {
            config.PluginEnabled = true;
            mouse.MouseDown += new EventHandler(mouse_MouseDown);
            mouse.MouseUp += new EventHandler(mouse_MouseUp);
            update = new Timer(3);
            update.Elapsed += new ElapsedEventHandler(update_Elapsed);
        }

        public void DisablePlugin()
        {
            config.PluginEnabled = false;
            update.Elapsed -= new ElapsedEventHandler(update_Elapsed);
            mouse.MouseDown -= new EventHandler(mouse_MouseDown);
            mouse.MouseUp -= new EventHandler(mouse_MouseUp);
        }

        #endregion

        [DllImport("User32.dll")]
        public static extern IntPtr GetDC(IntPtr hwnd);
        [DllImport("User32.dll")]
        public static extern void ReleaseDC(IntPtr hwnd, IntPtr dc);

        void update_Elapsed(object sender, ElapsedEventArgs e)
        {
            // this solution sucks balls
            DrawRegion(clickStart, clickEnd);
            clickEnd = mouse.Position;
        }

        void mouse_MouseUp(object sender, EventArgs e)
        {
            update.Stop();
            clickEnd = mouse.Position;
            int width = clickEnd.X - clickStart.X;
            int height = clickEnd.Y - clickStart.Y;
            if(width > 1 && height > 1){
                bitmap = CaptureScreenShot(clickStart, new Size(width, height));
                Save();
            }
        }

        void mouse_MouseDown(object sender, EventArgs e)
        {
            clickStart = mouse.Position;
            update.Start();
        }

        ~RegionShot()
        {
            if (mouse != null)
                mouse.Dispose();
        }

        public void DrawRegion(Point topleft, Point botright)
        {
            // hard to draw within fps, performance seems to be fucking poor
            SolidBrush b = new SolidBrush(Color.Red);
            IntPtr desktopDC = GetDC(IntPtr.Zero);
            Graphics g = Graphics.FromHdc(desktopDC);
            g.FillRectangle(b, topleft.X, topleft.Y, botright.X, botright.Y);
            g.Dispose();
            ReleaseDC(IntPtr.Zero, desktopDC);
        }

        public void Save()
        {
            string picPath = host.GetTempFileDir();
            string pic = string.Format("{0}\\{1}.png", picPath, DateTime.Now.ToString("MMddyyHmmss"));

            bitmap.Save(pic, ImageFormat.Jpeg);
            host.AddToUploadlist(pic);
            DisablePlugin();
        }

        /// <summary>
        /// Saves a picture of the defined screen to a bitmap image.
        /// </summary>
        /// <param name="src">UpperLeftSource</param>
        /// <param name="size">The picture size.</param>
        /// <returns>The saved bitmap.</returns>
        public static Bitmap CaptureScreenShot(Point src, Size size)
        {
            Bitmap bitmap = new Bitmap(size.Width, size.Height);

            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                graphics.CopyFromScreen(src, new Point(0, 0), size);
            }

            return bitmap;
        }
    }
}
